package routefinder.module;

import java.util.ArrayList;

// RouteStoreJiayuan.java
// Written by Jiayuan
// RouteStore component to add and compute
// distance between 2 connected locations

public class RouteStoreJiayuan extends RouteStore {
	private ArrayList<Location> locationList;
	private ArrayList<Location> visitedNodes;
	private double shortestDistance;

	public RouteStoreJiayuan() {
		locationList = new ArrayList<Location>();
	}

	public boolean addLocation(String location) {
		if (!locationList.contains(new Location(location))) {
			locationList.add(new Location(location));
			return true;
		}
		return false;
	} // end addLocation

	public boolean addPath(String fromLocation, String toLocation,
			double distance) {
		if (fromLocation.equals(toLocation))
			return false;
		Location start = new Location(fromLocation, 0);
		Location end = new Location(toLocation, distance);
		if (locationList.contains(start) && locationList.contains(end)) {
			// check if there is a direct path exist and update its distance
			int index = locationList.indexOf(end);
			Location next = locationList.get(index).getNextLocation(start);
			if (next == null) {
				index = locationList.indexOf(start);
				Location temp = locationList.get(index);
				next = temp.getNextLocation(end);
				if (next == null) {
					temp.setNextLocation(end);
					index = locationList.indexOf(end);
					locationList.get(index).setNextLocation(
							new Location(temp.getLocationName(), end
									.getDistance()));
				} else {
					next.setDistance(distance);
					index = locationList.indexOf(end);
					locationList.get(index).getNextLocation(start).setDistance(
							distance);
				}
			} else {
				next.setDistance(distance);
				index = locationList.indexOf(start);
				locationList.get(index).getNextLocation(end).setDistance(
						distance);
			}
			return true;
		} else
			return false;
	} // end addPath

	// a recursive method to compute the shortest distance
	// for all the possible path
	private double computeShortestPath(Location from, Location to,
			double shortest) {
		int index = locationList.indexOf(from);
		Location location = locationList.get(index);
		visitedNodes.add(location);
		Location next = location.getNextLocation();
		while (next != null) {
			if (!visitedNodes.contains(next)) {
				shortest += next.getDistance();
				if (next.equals(to)) {
					if (shortest < shortestDistance)
						shortestDistance = shortest;
				} else
					computeShortestPath(next, to, shortest);
				shortest -= next.getDistance();
			}
			next = next.getNextLocation();
		}
		return (shortestDistance == Double.MAX_VALUE) ? -1 : shortestDistance;
	} // end computeShortestPath

	public double getShortestDistance(String fromLocation, String toLocation) {
		shortestDistance = Double.MAX_VALUE;
		visitedNodes = new ArrayList<Location>();
		Location start = new Location(fromLocation);
		Location end = new Location(toLocation);
		if (locationList.contains(start) && locationList.contains(end)) {
			double distance = computeShortestPath(start, end, 0);
			return distance;
		}
		return -1;
	} // end getShortestDistance

} // end class RouteStoreJiayuan